﻿
#include "stdafx.h"
#include "FormulaWnd.h"
#include "MenuWnd.h"
#include "MatrixSizeWnd.h"
#include "Util.h"

CFormulaWnd::CFormulaWnd()
{
	::ZeroMemory(&m_rcFormula, sizeof(m_rcFormula));
	::ZeroMemory(&m_rcEdit, sizeof(m_rcEdit));
	m_ptOrigin = { 20, 20 };
	m_szFormula = { 20, 20 };
	m_bFormulaOK = false;
	m_bIsExternalTree = false;
	m_pBinTree = NULL;
}

CFormulaWnd::~CFormulaWnd()
{
	
}

LPCTSTR CFormulaWnd::GetWindowClassName() const
{
	return _T("UIFormulaFrame");
}

UINT CFormulaWnd::GetClassStyle() const
{
	return UI_CLASSSTYLE_DIALOG | CS_DBLCLKS;
}

CDuiString CFormulaWnd::GetSkinFile()
{
	return _T("formula.xml");
}

CDuiString CFormulaWnd::GetSkinFolder()
{
	return  _T("");
}

//LPCTSTR CFormulaWnd::GetResourceID() const
//{
//	return MAKEINTRESOURCE(IDR_ZIPRES1);
//}
//
//UILIB_RESOURCETYPE CFormulaWnd::GetResourceType() const
//{
//	return UILIB_ZIPRESOURCE;
//}

void CFormulaWnd::Init(CBinTree* pBinTree)
{
	if (pBinTree) {
		m_pBinTree = pBinTree;
		m_bIsExternalTree = true;

		m_ptOrigin = { pBinTree->m_ptOrigin.x, pBinTree->m_ptOrigin.y };
		pBinTree->TranslateTree(0 - pBinTree->m_ptOrigin.x, 0 - pBinTree->m_ptOrigin.y);
		pBinTree->TranslateTree(m_szFormula.cx, m_szFormula.cy);
		m_pCmbFontSize->SelectItem(m_pBinTree->GetRootNode()->GetFontSize() / 4 - 4, false, false);
		m_crColor = m_pBinTree->GetRootNode()->GetColor();
	}
	else {
		m_pBinTree = new CBinTree;
		//创建头结点
		m_pBinTree->CreateTree({ m_szFormula.cx, m_szFormula.cy }, m_crColor, GetSelectFontSize());
	}
}

CControlUI* CFormulaWnd::CreateControl(LPCTSTR pstrClass)
{
	if (_tcscmp(pstrClass, DUI_CTR_FORMULA) == 0) return new CFormulaUI;
	return NULL;
}

void CFormulaWnd::InitWindow()
{
	m_pBtnNew = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnNew")));
	m_pBtnDelete = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnDelete")));
	m_pBtnBakspace = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnBakspace")));
	m_pCmbFontSize= static_cast<CComboUI*>(m_PaintManager.FindControl(_T("cmbfontsize")));
	m_pBtnColor = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnColor")));
	m_crColor = kNodeColor;
	m_pBtnNum = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnNum")));
	m_pBtnSign = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnSign")));
	m_pBtnGreekAlphabet = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnGreekAlphabet")));
	m_pBtnAlphabet = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnAlphabet")));
	m_pBtnHandwriting = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnHandwriting")));
	m_pBtnLimit = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnLimit")));
	m_pBtnLogarithm = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnLogarithm")));

	m_pBtnSpecialSign = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnSpecialSign")));
	m_pBtnPower = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnPower")));
	m_pBtnRadical = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnRadical")));
	m_pBtnBrackets = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnBrackets")));
	m_pBtnIntegral = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnIntegral")));
	m_pBtnSum = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnSum")));
	m_pBtnFraction = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnFraction")));
	m_pBtnMatrix = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnMatrix")));
	m_pBtnArrow = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnArrow")));
	m_pBtnTaggedSign = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnTaggedSign")));
	m_pBtnLargeOperator = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnLargeOperator")));

	m_pBtnTrigonometric = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnTrigonometric")));
	m_pBtnInverseTrigonometric = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnInverseTrigonometric")));
	m_pBtnHyperbolicFunction = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnHyperbolicFunction")));
	m_pBtnKeyword = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnKeyword")));
	m_pBtnShortcuts = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnShortcuts")));

	m_pVlFormula = static_cast<CVerticalLayoutUI*>(m_PaintManager.FindControl(_T("vlFormula")));
	m_pCtrlFormula = static_cast<CFormulaUI*>(m_PaintManager.FindControl(_T("ctrlFormula")));
	if (m_pCtrlFormula == NULL)
		Close();

	m_pBtnOK = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("btnOK")));

	//响应OnChange(EM_SETEVENTMASK 设置 ENM_CHANGE)
	long lMask = m_pCtrlFormula->GetEventMask();
	lMask |= ENM_CHANGE;
	lMask &= ~ENM_PROTECTED;
	m_pCtrlFormula->SetEventMask(lMask);

	m_PaintManager.SetNextTabControl(false);
}

void CFormulaWnd::OnFinalMessage(HWND hWnd)
{
	if (m_bFormulaOK || m_bIsExternalTree) {
		RECT rc = m_pBinTree->GetRootNode()->GetRect();
		m_pBinTree->TranslateTree(0 - rc.left, 0 - rc.top);
		m_pBinTree->SetSelectNode(NULL);//当前选中节点由文本框来显示，当公式编辑器窗口关闭时需要把选中节点指向别处
	}
	if (m_bIsExternalTree)
		m_pBinTree->TranslateTree(m_ptOrigin.x, m_ptOrigin.y);

	if (m_bFormulaOK) {
		if (m_bIsExternalTree)
			::SendMessage(GetParent(hWnd), WM_FORMULAWND_OK, 0, 0);
		else
			::SendMessage(GetParent(hWnd), WM_FORMULAWND_OK, 0, LPARAM(m_pBinTree));
	}
	else {
		::SendMessage(GetParent(hWnd), WM_FORMULAWND_CANCEL, 0, 0);
		if (!m_bIsExternalTree)
			delete m_pBinTree;
	}

	__super::OnFinalMessage(hWnd);

	delete this;
}

LRESULT CFormulaWnd::OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	bHandled = FALSE;
	if ((wParam >= 'A' && wParam <= 'Z') || (wParam >= 'a' && wParam <= 'z')) {
		TCHAR strOperator[MAX_PATH];
		::ZeroMemory(&strOperator, sizeof(strOperator));
		CharToTchar((CHAR*)&wParam, strOperator);
		HandleMessage(WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_ALPHABET, (LPARAM)(LPVOID)strOperator);

		bHandled = TRUE;
	}
	return 0;
}

LRESULT CFormulaWnd::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	bHandled = FALSE;

	POINT point;
	GetCaretPos(&point);
	int charpos = m_pCtrlFormula->CharFromPos(point);
	int charsum = m_pCtrlFormula->GetTextLength();
	long nStartChar = 0, nEndChar = 0;
	m_pCtrlFormula->GetSel(nStartChar, nEndChar);
	if (LOWORD(wParam) == VK_BACK && charpos == 0 && nStartChar == 0 && nEndChar == 0) {//BS (backspace)//处理删除节点
		if (m_pBinTree->DelNode(VK_BACK)) {
			UpdateEditInput(m_pBinTree->GetSelectedNode());

			int charsum2 = m_pCtrlFormula->GetTextLength();
			m_pCtrlFormula->SetSel(charsum2 - charsum, charsum2 - charsum);

			bHandled = TRUE;
		}
	}
	else if (LOWORD(wParam) == VK_DELETE && charpos == charsum && nStartChar == charsum && nEndChar == charsum) {//DEL (delete)
		if (m_pBinTree->DelNode(VK_DELETE)) {
			UpdateEditInput(m_pBinTree->GetSelectedNode());

			m_pCtrlFormula->SetSel(charsum, charsum);

			bHandled = TRUE;
		}
	}
	else if (LOWORD(wParam) == VK_RETURN) {//Enter
		m_pBinTree->CreateNode(NT_LINE, charpos, 0, 0);
		UpdateEditInput(m_pBinTree->GetSelectedNode());
		bHandled = TRUE;
	}
	else if (LOWORD(wParam) == VK_LEFT && charpos == 0) {//左移光标
		if (CNode* pNode = m_pBinTree->GetSelectedNode()->GetLeftJointNode(true)) {
			UpdateEditInput(pNode);
			bHandled = TRUE;
		}
	}
	else if (LOWORD(wParam) == VK_RIGHT && charpos == charsum) {//右移光标
		if (CNode* pNode = m_pBinTree->GetSelectedNode()->GetRightJointNode(true)) {
			UpdateEditInput(pNode);
			__super::HandleMessage(WM_KEYDOWN, VK_HOME, 0);
			__super::HandleMessage(WM_KEYUP, VK_HOME, 0);
			bHandled = TRUE;
		}
	}
	else {
		switch (LOWORD(wParam))
		{
		case 'F':
		case '6':
		case 'R':
		case 'G':
		case 'J':
		case '9':
		case 'I':
		case VK_OEM_4:
		case 'S':
		case 'H':
		case 'L':
		case 'M':
			if (GetKeyState(VK_CONTROL) < 0) {
				if (LOWORD(wParam) == 'F')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_FRACTION, 0);
				else if (LOWORD(wParam) == '6')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_SUPERSCRIPT, 0);
				else if (LOWORD(wParam) == 'R')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_RADICAL, 1);
				else if (LOWORD(wParam) == 'G')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_LOGARITHM, 0);
				else if (LOWORD(wParam) == 'J')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_MIDTOPBOTTOM, 0);
				else if (LOWORD(wParam) == '9')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_PARENTHESES, MAKELPARAM(1, 0));
				else if (LOWORD(wParam) == 'I')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_INTEGRAL, (LPARAM)2);
				else if (LOWORD(wParam) == VK_OEM_4)
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_BRACKETS, MAKELPARAM(1, 0));
				else if (LOWORD(wParam) == 'S')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_SUM, (LPARAM)2);
				else if (LOWORD(wParam) == 'H')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_BRACES, MAKELPARAM(1, 0));
				else if (LOWORD(wParam) == 'L')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_LIMIT, 0);
				else if (LOWORD(wParam) == 'M')
					::SendMessage(m_hWnd, WM_FORMULA_CREATENODE, (WPARAM)(LPVOID)NT_MATRIX, MAKELPARAM(3, 3));

				bHandled = TRUE;
			}
			break;
		default:
			break;
		}
	}
	//TCHAR szbuf[MAX_PATH];
	//wsprintf(szbuf, _T("uMsg = %d, wParam = %d, lParam = %d, bHandled = %d\n"), uMsg, wParam, lParam, bHandled);
	//OutputDebugString(szbuf);
	return 0;
}

LRESULT CFormulaWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT lRes = 0;
	BOOL bHandled = TRUE;

	switch (uMsg)
	{
	case WM_FORMULA_CHANGECOLOR:
	{
		m_crColor = ARGBToRGB((COLORREF)wParam);
		m_pBinTree->ChangeColor(m_crColor);
		m_pCtrlFormula->SetTextColor(RGBToARGB(255, m_pBinTree->GetRootNode()->GetColor()));
		InvalidateRect(m_hWnd, &m_rcFormula, false);
		UpdateWindow(m_hWnd);
	}
		break;
	case WM_FORMULA_CREATENODE:
	{
		//AttachThreadInput(GetCurrentThreadId(), ::GetWindowThreadProcessId(m_hWnd, NULL), TRUE);
		POINT point;
		GetCaretPos(&point);
		int charpos = m_pCtrlFormula->CharFromPos(point);
		m_pBinTree->CreateNode((LPCTSTR)wParam, charpos, lParam, 0);
		UpdateEditInput(m_pBinTree->GetSelectedNode());
		__super::HandleMessage(WM_KEYDOWN, VK_HOME, 0);
		__super::HandleMessage(WM_KEYUP, VK_HOME, 0);
	}
		break;
	case WM_FORMULA_INSERTCHAR:
		TCHAR strOperator[MAX_PATH];
		::ZeroMemory(&strOperator, sizeof(strOperator));
		CharToTchar((CHAR*)&wParam, strOperator);
		InsertCharsIntoEditInput(strOperator);
		break;
	case WM_FORMULA_INSERTCHARS:
		InsertCharsIntoEditInput((LPCTSTR)wParam);
		break;
	case WM_FORMULA_CREATEFORMULA:
	{
		POINT point;
		GetCaretPos(&point);
		int charpos = m_pCtrlFormula->CharFromPos(point);

		TCHAR pstrFilename[MAX_PATH] = { 0 };//用于接收文件名
		_tcscpy(pstrFilename, _T("formulatxtres\\"));
		_tcscat(pstrFilename, (LPCTSTR)wParam);

        //从资源中价值文件
        DWORD dwSize = CResourceZipManager::GetResourceZipItemData(pstrFilename, NULL, 0);
        if (dwSize > 0) {
            BYTE* pByte = new BYTE[dwSize];
            if (CResourceZipManager::GetResourceZipItemData(pstrFilename, pByte, dwSize) > 0) {
                TCHAR *strFormulaText = NULL;
#ifdef _UNICODE
                DWORD length = MultiByteToWideChar(CP_ACP, NULL, (LPCSTR)pByte, -1, NULL, 0);
                strFormulaText = new TCHAR[length];
                MultiByteToWideChar(CP_ACP, NULL, (LPCSTR)pByte, -1, strFormulaText, length);
#else
                strFormulaText = new CHAR[dwSize + 1];
                ::CopyMemory(strFormulaText, pByte, dwSize * sizeof(TCHAR));
                strFormulaText[dwSize] = 0;
#endif
                if (m_pBinTree->CreateFormulaTree(strFormulaText, charpos)) {
                    UpdateEditInput(m_pBinTree->GetSelectedNode());
                }
                delete[] strFormulaText;
            }
            delete[] pByte;
        }
	}
		break;
	case WM_FORMULA_MATRIXMN:
	{
		CMatrixSizeWnd* pMatrixSize = new CMatrixSizeWnd(m_hWnd, _T("MatrixSize.xml"));
		CDuiPoint point = { 200, 200 };
		ClientToScreen(m_hWnd, &point);
		pMatrixSize->Init(m_hWnd, point);
	}
		break;
	case WM_LBUTTONDOWN:
	{
		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		if (PtInRect(&m_rcFormula, pt)) {
			POINT pt2 = pt;
			SIZE sz = m_pVlFormula->GetScrollPos();
			pt2.x += sz.cx - m_rcFormula.left;
			pt2.y += sz.cy - m_rcFormula.top;
			if (CNode* pNode = m_pBinTree->GetNodeFromPoint(pt2)) {
				if (pNode != m_pBinTree->GetSelectedNode())
					UpdateEditInput(pNode);
				else {
					m_PaintManager.SetFocus(m_pVlFormula);
					m_PaintManager.SetFocus(m_pCtrlFormula);
				}
			}
		}
		bHandled = FALSE;
	}
		break;
	default:
		bHandled = FALSE;
		break;
	}
	if (bHandled) return lRes;

	return __super::HandleMessage(uMsg, wParam, lParam);
}

void CFormulaWnd::OnPrepare()
{
	m_rcFormula = m_pVlFormula->GetPos();
	m_pCtrlFormula->InitTree(m_pBinTree);
	CNode* pNode = m_pBinTree->GetRootNode()->GetLeftEditNode(m_pBinTree->GetRootNode());
	UpdateEditInput(pNode);
}

void CFormulaWnd::Notify(TNotifyUI& msg)
{
	if (msg.sType == _T("windowinit")) {
		OnPrepare();
	}
	else if (msg.sType == _T("click")) {
		if (msg.pSender == m_pBtnNew) {
			delete m_pBinTree->GetRootNode();
			POINT pt = { m_szFormula.cx, m_szFormula.cy };
			m_pBinTree->CreateTree(pt, m_crColor, GetSelectFontSize());
			UpdateEditInput(m_pBinTree->GetSelectedNode());
		}
		else if (msg.pSender == m_pBtnDelete) {
			::SendMessage(m_hWnd, WM_KEYDOWN, WPARAM(VK_DELETE), 0);
		}
		else if (msg.pSender == m_pBtnBakspace) {
			::SendMessage(m_hWnd, WM_KEYDOWN, WPARAM(VK_BACK), 0);
		}
		else if (msg.pSender == m_pBtnColor) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menucolorres\\MenuColor.xml"));
			RECT rc = m_pBtnColor->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnNum) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menunumres\\MenuNum.xml"));
			RECT rc = m_pBtnNum->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnSign) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menusignres\\MenuSign.xml"));
			RECT rc = m_pBtnSign->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnGreekAlphabet) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menugreekalphabetres\\MenuGreekAlphabet.xml"));
			RECT rc = m_pBtnGreekAlphabet->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnAlphabet) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menualphabetres\\MenuAlphabet.xml"));
			RECT rc = m_pBtnAlphabet->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnHandwriting) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuhandwritingres\\MenuHandwriting.xml"));
			RECT rc = m_pBtnHandwriting->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnLimit) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menulimitres\\MenuLimit.xml"));
			RECT rc = m_pBtnLimit->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnLogarithm) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menulogarithmres\\MenuLogarithm.xml"));
			RECT rc = m_pBtnLogarithm->GetPos();
			POINT point = { rc.left, rc.bottom };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnSpecialSign) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuspecialsignres\\MenuSpecialSign.xml"));
			RECT rc = m_pBtnSpecialSign->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnPower) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menupowerres\\MenuPower.xml"));
			RECT rc = m_pBtnPower->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnRadical) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuradicalres\\MenuRadical.xml"));
			RECT rc = m_pBtnRadical->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnBrackets) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menubracketsres\\MenuBrackets.xml"));
			RECT rc = m_pBtnBrackets->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnIntegral) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuintegralres\\MenuIntegral.xml"));
			RECT rc = m_pBtnIntegral->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnSum) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menusumres\\MenuSum.xml"));
			RECT rc = m_pBtnSum->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnFraction) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menufractionres\\MenuFraction.xml"));
			RECT rc = m_pBtnFraction->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnMatrix) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menumatrixres\\MenuMatrix.xml"));
			RECT rc = m_pBtnMatrix->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnArrow) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuarrowres\\MenuArrow.xml"));
			RECT rc = m_pBtnArrow->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnTaggedSign) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menutaggedsignres\\MenuTaggedSign.xml"));
			RECT rc = m_pBtnTaggedSign->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnLargeOperator) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menulargeoperatorres\\MenuLargeOperator.xml"));
			RECT rc = m_pBtnLargeOperator->GetPos();
			POINT point = { rc.right, rc.top };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnTrigonometric) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menutrigonometricres\\MenuTrigonometric.xml"));
			RECT rc = m_pBtnTrigonometric->GetPos();
			POINT point = { rc.left, rc.top - 119 };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnInverseTrigonometric) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuinversetrigonometricres\\MenuInverseTrigonometric.xml"));
			RECT rc = m_pBtnInverseTrigonometric->GetPos();
			POINT point = { rc.left, rc.top - 148 };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnHyperbolicFunction) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menuhyperbolicfunctionres\\MenuHyperbolicFunction.xml"));
			RECT rc = m_pBtnHyperbolicFunction->GetPos();
			POINT point = { rc.left, rc.top - 182 };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnKeyword) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menukeywordres\\MenuKeyword.xml"));
			RECT rc = m_pBtnKeyword->GetPos();
			POINT point = { rc.left, rc.top - 124 };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnShortcuts) {
			CMenuWnd* pMenu = new CMenuWnd(m_hWnd, _T("menushortcutsres\\MenuShortcuts.xml"));
			RECT rc = m_pBtnShortcuts->GetPos();
			POINT point = { rc.left, rc.top - 196 };
			ClientToScreen(m_hWnd, &point);
			pMenu->Init(m_hWnd, point);
		}
		else if (msg.pSender == m_pBtnOK) {
			m_bFormulaOK = true;
			Close();
		}
	}
	else if (msg.sType == _T("itemselect")) {
		if (msg.pSender == m_pCmbFontSize) {
			m_pBinTree->ChangeFontSize(GetSelectFontSize());
			CNode* pNode = m_pBinTree->GetSelectedNode();
			m_pCtrlFormula->SetFont(pNode->GetFaceName(), pNode->GetFontSize(), false, false, false);
			UpdateRichEditPos();
		}
	}
	else if (msg.sType == _T("textchanged")) {
		if (msg.pSender == m_pCtrlFormula) {
			m_pBinTree->UpdateSelectNode(m_pCtrlFormula->GetText().GetData());
			UpdateRichEditPos();
			return;
		}
	}
	else if (!_tcsicmp(msg.sType, _T("scroll"))) {
		UpdateRichEditPos();
	}
	//OutputDebugString(msg.pSender->GetName());
	//OutputDebugString(_T(":"));
	//OutputDebugString(msg.sType);
	//OutputDebugString(_T("\n"));
	return __super::Notify(msg);
}

void CFormulaWnd::UpdateEditInput(CNode* pNode)
{
	if (pNode) {
		m_pBinTree->SetSelectNode(pNode);
		m_pCtrlFormula->SetText(pNode->GetText());//会触发textchange事件
		m_pCtrlFormula->SetFont(pNode->GetFaceName(), pNode->GetFontSize(), false, false, false);//会触发textchange事件
		m_pCtrlFormula->SetTextColor(RGBToARGB(255,pNode->GetColor()));//会触发textchange事件
		if (!lstrlen(m_pBinTree->GetSelectedNode()->GetText()) && !_tcscmp(m_pCtrlFormula->GetText(), m_pBinTree->GetSelectedNode()->GetText()))
			m_PaintManager.SendNotify(m_pCtrlFormula, DUI_MSGTYPE_TEXTCHANGED);
	}
}

void CFormulaWnd::UpdateRichEditPos()
{
	m_PaintManager.SetFocus(m_pVlFormula);
	m_rcEdit = m_pBinTree->GetSelectedNode()->GetRect();

	SIZE sz = m_pVlFormula->GetScrollPos();
	m_rcEdit.left -= sz.cx;
	m_rcEdit.top -= sz.cy;
	m_rcEdit.right -= sz.cx;
	m_rcEdit.bottom -= sz.cy;
	m_pCtrlFormula->SetTextHostPos(m_rcEdit);
	
	m_PaintManager.SetFocus(m_pCtrlFormula);
	//m_pCtrlFormula->Invalidate();//当公式树宽高减小时更新滚动条
}

int CFormulaWnd::GetSelectFontSize()
{
	//真正显示的字体大小
	return _ttoi(m_pCmbFontSize->GetText());
}

void CFormulaWnd::InsertCharsIntoEditInput(LPCTSTR strInsert)
{
	m_pCtrlFormula->ReplaceSel(strInsert, false);
}
